package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.service.TestService;
import lombok.SneakyThrows;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class TestServiceImpl implements TestService {

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 写Redis测试
     */
    @Override
    public void setRedis() {
        // 使用Redis的setnx操作
        Boolean flag = redisTemplate.opsForValue().setIfAbsent("lock", "aaaa",10, TimeUnit.SECONDS);
        // 若key存在，则set失败，返回false --- 加锁
        if (flag){
            try {
                // 从Redis中获取一个key=test的value
                Integer test = (Integer)redisTemplate.opsForValue().get("test");
                if (test != null){
                    // 若value不为null则++
                    test++;
                    // 重置
                    redisTemplate.opsForValue().set("test",test);
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                // 释放锁
                redisTemplate.delete("lock");
            }
        }else {
            // 加锁失败的场合 -- 再次尝试
            setRedis();
        }
    }


    @Autowired
    RedissonClient redissonClient;

    @SneakyThrows
    @Override
    public void setRedisLockByRedission() {
        // 获取锁
        RLock lock = redissonClient.getLock("lock_test");
        // 加锁
        if (lock.tryLock()){
            // 加锁成功
            try {
                // 从Redis中获取一个key=test的value
                Integer test = (Integer)redisTemplate.opsForValue().get("test");
                if (test != null){
                    // 若value不为null则++
                    test++;
                    // 重置
                    redisTemplate.opsForValue().set("test",test);
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                // 释放锁
                lock.unlock();
            }
        }
    }
}
